﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using ICSharpCode.SharpZipLib.Checksums;
using System.Data;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
using System.IO.Compression;
using ICSharpCode.SharpZipLib;

namespace Ehai.Web.Framework
{
    /// <summary>
    /// 
    /// </summary>
    public class DisplayInfo
    {
        private static string strBack = String.Empty;
        private static bool bStatus = false;
        private static int disLen = 60;
        /// <summary>
        /// Show
        /// </summary>
        /// <param name="front"></param>
        /// <param name="info"></param>
        public static void Show(string front, string info)
        {
            if (strBack == String.Empty)
            {
                int disLen1 = disLen + 16;
                for (int k = 0; k < disLen1; k++)
                {
                    strBack += "\b";
                }
                for (int k = 0; k < disLen1; k++)
                {
                    strBack += " ";
                }
                for (int k = 0; k < disLen1; k++)
                {
                    strBack += "\b";
                }
            }

            int l = info.Length;
            string tt = String.Empty;
            if (l > disLen) tt = "...";

            int m1 = l > disLen ? disLen-3 : l, m2 = l - m1;
            string t;
            if (bStatus)
            {
                t = "\\";
                bStatus = false;
            }
            else
            {
                t = "/";
                bStatus = true;
            }
            Console.Write(strBack);
            Console.Write(t + " " + front + tt + info.Substring(m2, m1));
        }
    }

    /// <summary>
    /// 提供压缩与解压缩的类
    /// </summary>
    public class Zip
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceZip"></param>
        /// <param name="desPath"></param>
        /// <param name="cover"></param>
        public static void UnzipFiles(string sourceZip, string desPath, bool cover)
        {
            ZipInputStream stream = new ZipInputStream(File.OpenRead(sourceZip));
            ZipEntry theEntry;


            if (desPath[desPath.Length - 1] != Path.DirectorySeparatorChar)
                desPath += Path.DirectorySeparatorChar;

            while ((theEntry = stream.GetNextEntry()) != null)
            {

                string directoryName = Path.GetDirectoryName(theEntry.Name);
                string fileName = Path.GetFileName(theEntry.Name);

                if (directoryName != String.Empty)
                {
                    if (Directory.Exists(desPath + directoryName) && cover == false)
                    {
                        throw new Exception("文件夹已存在！");
                    }
                    else
                    {
                        FoldHandle.CreateDirectory(desPath + directoryName);
                        cover = true;
                    }
                }


                if (fileName != String.Empty)
                {
                    FileStream streamWriter = File.Create(desPath + theEntry.Name);

                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = stream.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }

                    streamWriter.Close();
                }
            }
            stream.Close();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceFile">文件名</param>
        /// <param name="desPath">路径</param>
        public static void Cover(string sourceFile, string desPath)
        {
            if (desPath[desPath.Length - 1] != Path.DirectorySeparatorChar)
                desPath += Path.DirectorySeparatorChar;
            string[] fileList = Directory.GetFileSystemEntries(desPath);
            foreach (string file in fileList)
            {
                if (Directory.Exists(file))
                {
                    Cover(sourceFile, file);
                }
                else
                {
                    if (Path.GetFileName(file) == Path.GetFileName(sourceFile))
                    {
                        //string Des=Path.GetDirectoryName(file);
                        string Des = Path.GetFullPath(file);
                        FileInfo myFile = new FileInfo(sourceFile);
                        myFile.CopyTo(Des, true);
                    }
                }
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strFile"></param>
        /// <param name="strZip"></param>
        public static void ZipFile(string strFile, string strZip)
        {

            //string[] filenames = Directory.GetFiles(strFile);

            if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar)
                strFile += Path.DirectorySeparatorChar;

            if (!(new FileInfo(strZip)).Directory.Exists)
            {
                FoldHandle.CreateDirectory((new FileInfo(strZip)).Directory.FullName);
            }
            ZipOutputStream s = new ZipOutputStream(File.Create(strZip));

            s.SetLevel(6); // 0 - store only to 9 - means best compression
            zip(strFile, s, strFile);


            s.Finish();
            s.Close();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strZip"></param>
        /// <param name="srcDict"></param>
        /// <param name="basePath"></param>
        public static void ZipFileFromDict(string strZip, Dictionary<string, List<string>> srcDict,string basePath)
        {

            //string[] filenames = Directory.GetFiles(strFile);

            if (!(new FileInfo(strZip)).Directory.Exists)
            {
                FoldHandle.CreateDirectory((new FileInfo(strZip)).Directory.FullName);
            }

            ZipOutputStream s = new ZipOutputStream(File.Create(strZip));

            s.SetLevel(6); // 0 - store only to 9 - means best compression
            zip(srcDict, s, strZip, basePath);

            s.Finish();
            s.Close();
        }

        private static void zip(Dictionary<string, List<string>> srcDict, ZipOutputStream s, string zipFileName,string basePath)
        {
            Crc32 crc = new Crc32();

            //Console.WriteLine("系统正在备份中（备份文件为：" + zipFileName + "）.....");

            foreach (KeyValuePair<string, List<string>> kvpList in srcDict)
            {

                //Console.WriteLine("\n备份 " + kvpList.Key + "文件");

                for (int j = 0; j < kvpList.Value.Count; j++)
                {

                    //DisplayInfo.Show("备份文件：", kvpList.Value[j]);

                    FileStream fs = File.OpenRead(kvpList.Value[j]);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    string tempfile = kvpList.Value[j].Replace(basePath, String.Empty);//, file.Length - strFile.Length + 2);
                    tempfile = tempfile.TrimStart(Path.DirectorySeparatorChar);
                    ZipEntry entry = new ZipEntry(tempfile);

                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    fs.Close();

                    crc.Reset();
                    crc.Update(buffer);

                    entry.Crc = crc.Value;

                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                }
            }
        }

        private static void zip(string strFile, ZipOutputStream s, string staticFile)
        {
            if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar)
                strFile += Path.DirectorySeparatorChar;
            Crc32 crc = new Crc32();
            string[] filenames = Directory.GetFileSystemEntries(strFile);
            foreach (string file in filenames)
            {

                if (Directory.Exists(file))
                {
                    if (Path.GetFileName(file).ToLower() != "bin" && Path.GetFileName(file).ToLower() != "bak")//&& Path.GetFileName(file).IndexOf("备份")<0
                        zip(file, s, staticFile);
                }

                else
                {
                    FileStream fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    string tempfile = file.Substring(staticFile.LastIndexOf("\\") + 1);//, file.Length - strFile.Length + 2);
                    ZipEntry entry = new ZipEntry(tempfile);

                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    fs.Close();

                    crc.Reset();
                    crc.Update(buffer);

                    entry.Crc = crc.Value;

                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                }
            }
        }

        private void Delete(string StoreFile)
        {
            Directory.Delete(StoreFile, true);
        }

        //public static string  StoreFile = @"d:\cc\";
        //static void Main(string[] args)
        //{

        //    string strZip = @"d:\a.zip";
        //    //string strFile = @"d:\cc\";
        //    string strSourceFile = @"d:\as.txt";

        //    string text1 = null;
        //    Guid guid1 = Guid.NewGuid();
        //    text1 = guid1.ToString("n");
        //    string StoreFile = Path.GetPathRoot(strZip) + text1 + "\\";
        //    if (File.Exists(StoreFile))
        //    {
        //        guid1 = Guid.NewGuid();
        //        text1 = guid1.ToString("n");
        //    }
        //    Zip Zc = new Zip();
        //    Zc.UnzipFiles(strZip, StoreFile, true);
        //    Zc.Cover(strSourceFile, StoreFile);
        //    Zc.ZipFile(StoreFile, strZip);
        //    Zc.Delete(StoreFile);
        //}
    }
}
